#include "net.h"
#include <poll.h>
#include <unistd.h>
#include <fcntl.h>

#define READWAIT 12

int ConnectToHost(const char *hostname, const char *port)
{
	int sock;
	struct addrinfo hints, *result;

	printf("Connecting: %s:%s... ", hostname, port);
	fflush(stdout);

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
	if (getaddrinfo(hostname, port, &hints, &result))
	{
		printf("FAILED\n");
		return -1;
	}
	if ((sock = socket(hints.ai_family, hints.ai_socktype, 0)) == -1)
	{
		printf("FAILED\n");
		return -1;
	}

	int error;
	int timeout = 2;
	int fret =fcntl(sock,F_GETFL,0);		//save the sockets properties
	fcntl(sock,F_SETFL,fret | O_NONBLOCK);		//set the socket to nonblocking
	error = connect(sock,result->ai_addr,result->ai_addrlen);	//start the connect
	struct pollfd pfd;
	pfd.fd = sock;					//going to monitor the socket until connect completes
	pfd.events = POLLIN|POLLOUT;			//interested in being able to read and write to this socket
	pfd.revents = 0;
	int ready = poll(&pfd,1,timeout*1000);
	if ((ready==0) || ((pfd.revents&POLLHUP || pfd.revents&POLLERR)))
	{
		printf("FAILED\n");
		freeaddrinfo(result);
		return -1;
	}
	fcntl(sock,F_SETFL,fret);	//reset the socket to blocking
//	if (connect(sock, result->ai_addr, result->ai_addrlen))
//	{
//	    printf("connect failed!\n");
//	    return -1;
//	}
	freeaddrinfo(result);

	printf("SUCCESS\n");
	return sock;
}

bool ReadFromSocket(int sock, unsigned char *dest, unsigned size)
{
	struct pollfd pfd;
	pfd.fd = sock;
	pfd.events = POLLIN;
	pfd.revents = 0;
	unsigned numRead = 0;
	while (numRead < size)
	{
		int ready = poll(&pfd,1,READWAIT*1000);
		if(ready==0)
			return false;
		if(!pfd.revents&POLLIN)
			return false;
		int tmpRead = read(sock, &(dest[numRead]), size-numRead);
		if (tmpRead < 1)
			break;
		numRead += tmpRead;
	}
	if (numRead < 1)
	{
		return false;
	}
	return true;
}

unsigned SwapEndian(unsigned *orig)
{
	unsigned ret = (((unsigned char*)orig)[0]&0x000000FF)<<24;
	ret += (((unsigned char*)orig)[1] & 0x000000FF)<<16;
	ret += (((unsigned char*)orig)[2] & 0x000000FF)<<8;
	ret += (((unsigned char*)orig)[3] & 0x000000FF);
	return ret;
}
